﻿using Se.Log;
using Se.Model.Data;
using Se.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Reflection;

namespace Se.Model.Template.Common
{
    public class CSVReader : IFileReader
    {
        public CSVReader(string filePath)
        {
            this.m_FilePath = filePath;
        }

        /// <summary>
        /// 路径
        /// </summary>
        string m_FilePath;

        public T[] ReadFile<T>() where T : DataEntityBase
        {
            string fileName = Path.Combine(this.m_FilePath, typeof(T).Name + ".csv");

            Dictionary<string, PropertyAccessor> propertyAccessorSet = new Dictionary<string, PropertyAccessor>();
            Dictionary<string, PropertyInfo> propertySet = new Dictionary<string, PropertyInfo>();
            foreach (var property in typeof(T).GetProperties())
            {
                propertyAccessorSet.Add(property.Name, new PropertyAccessor(property));
                propertySet.Add(property.Name, property);
            }

            List<T> entities = new List<T>();
            var strLines = File.ReadAllLines(fileName);
            List<string> titles = new List<string>();//CSV 第一行Title
            bool isTitle = true;
            try
            {
                foreach (var str in strLines)
                {
                    if (isTitle)
                    {
                        titles = str.Split(',').ToList();
                        isTitle = false;
                        continue;
                    }
                    var entity = (T)System.Activator.CreateInstance(typeof(T));
                    var fields = str.Split(',');
                    for (var i = 0; i < fields.Length; i++)
                    {
                        propertyAccessorSet[titles[i]].SetValue(entity, this.ChangeType(fields[i], propertySet[titles[i]].PropertyType));
                    }
                    entities.Add(entity);
                }
            }
            catch (Exception ex)
            {
                SeLog.Error("CSVReader->ReadCSV:{0}", ex.ToString());
            }

            return entities.ToArray();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private object ChangeType(string obj, Type type)
        {
            if (type.Equals(typeof(DateTime)))
            {
                return DateTime.Parse((string)obj);
            }
            else
            {
                return Convert.ChangeType(obj, type);
            }
        }
    }
}
